/*
 * author      : 吴中勤 
 * date        : 2018/8/28
 * description : 负责完成:
 * - 如果若干次 SapConfig.RETRY_COUNT_FOR_HTTP_EXCEPTION 请求失败 IOException , 则重试
 * - 记录每次日志
 */

package com.deepexi.adapter.converter.sap;

import com.deepexi.adapter.common.exception.HttpNon200Exception;
import com.deepexi.adapter.common.sdk.RequestInfo;
import com.deepexi.adapter.log.Log4Request;
import com.deepexi.adapter.log.LogRecorder;
import com.deepexi.adapter.sdk.sap.SapSdk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class SapSdkIntercepter {
    @Autowired
    private LogRecorder logRecorder;

    @Autowired
    private SapSdk sapSdk;

    @Autowired
    private SapConverterContext sapConverterContext;

    private static final int RETRY_COUNT_FOR_HTTP_EXCEPTION = 3;

    private static final Logger logger = LoggerFactory.getLogger(SapSdkIntercepter.class);

    /** 多次尝试 http请求, 知道成功或失败达到上限 */
    public String doHttpAndLogWithRetryIfFail(RequestInfo requestInfo) throws IOException, HttpNon200Exception {
        IOException lastEx = null;
        for (int count = 1; count <= RETRY_COUNT_FOR_HTTP_EXCEPTION; count++) {
            logger.info("count={}, url={}", count, requestInfo.url);
            try {
                return doHttpAndSaveLog(requestInfo);
            } catch (IOException ex) {
                logger.error("http 异常:", ex);
                lastEx = ex;
            }
        }
        throw lastEx;
    }

    /** 每次请求, 记录日志 */
    private String doHttpAndSaveLog(RequestInfo requestInfo) throws IOException, HttpNon200Exception {
        String response = "";
        String errorStr = "";
        Long timeCost;
        IOException theEx1 = null;
        HttpNon200Exception theEx2 = null;

        Long start = System.currentTimeMillis();
        try {
            // do http for string result
            response = sapSdk.doHttp(requestInfo);
        } catch (IOException ex) {
            errorStr = "Sap接口:网络异常" + ex;
            theEx1 = ex;
        } catch (HttpNon200Exception ex) {
            errorStr = "Sap接口:返回非200" + ex;
            theEx2 = ex;
        }
        timeCost = System.currentTimeMillis() - start;

        Log4Request log4Request = new Log4Request()
                .setFromSide("adapter")
                .setToSide("sap")
                .setReqId(requestInfo.reqId)
                .setUrl(requestInfo.url)
                .setRequest(requestInfo.strBody)
                .setApiType(requestInfo.apiType)
                .setErrorStr(errorStr)
                .setResponse(response)
                .setTimeCost(timeCost);

        // 拷贝上下文中记录的信息
        BeanUtils.copyProperties(sapConverterContext.getLogContext(), log4Request);

        // 同步记录 TODO 改成异步
        logRecorder.record(log4Request);
        if (null != theEx1) throw theEx1;
        if (null != theEx2) throw theEx2;
        return response;
    }
}
